﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;

namespace BerkelyAlgorithem2
{

    class ElectionProccess
    {
        public long UUID;
        private NeighbourTable Neighbours;
        System.Threading.Thread[] newThreads;
        Neighbour self;

        public ElectionProccess(NeighbourTable table, System.Threading.Thread[] threads)
        {
            this.Neighbours = table;
            findSelf();
            UUID = utils.getAddressAsInt(self.Address.ToString());
            newThreads = threads;

        }
       ~ElectionProccess()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        public ElectionProccess(NeighbourTable table)
        {
            this.Neighbours = table;
            findSelf();
            UUID = utils.getAddressAsInt(self.Address.ToString());

        }



        public bool start()
        {
            Neighbour master = findMaster();

            if (master.Address.ToString().Equals(self.Address.ToString()))
            {
                //broadCast("MASTER-" + master.Address.ToString()); //'secret' msg
                return true;
            }
            else
            {
                return false;
            }
        }



        public void broadCast(string str)
        {
            tcpClient cli;
            foreach (Neighbour n in Neighbours.Neighbours)
            {
                if (!n.Address.ToString().Equals(utils.FindLanAddress().ToString()))
                {
                    cli = new tcpClient(n.Address, n.Port);
                    try
                    {
                        cli.sendMsg(str);
                    }
                    catch
                    {
                        n.IsAlive = false;
                    }
                    cli.exit();
                }
            }
        }


        private void findSelf()
        {
            foreach (Neighbour n in Neighbours.Neighbours)
            {
                if (n.Address.Equals(utils.FindLanAddress()))
                {
                    self = n;
                }
            }
        }

        public Neighbour findMaster()
        {
            Neighbour temp=null;
            long max = 0;
            foreach (Neighbour n in Neighbours.Neighbours)
            {
                if (n.IsAlive)
                {
                    long test = utils.getAddressAsInt(n.Address.ToString());
                    if (test > max)
                    {
                        max = test;
                        n.IsMaster = false;
                        temp = n;
                    }
                }
            }
            if (temp != null)
            {
                temp.IsMaster = true;
                return temp;
            }
            else
            {
                //ALL MY FRIENDS ARE DEAD!!! KAMIKAZE!!!!!
                Environment.Exit(0);
            }
            return null;
        }
    }
}
